package com.xin.usermanagebackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xin.usermanagebackend.constant.ResultCode;
import com.xin.usermanagebackend.constant.UserConstant;
import com.xin.usermanagebackend.exception.BusinessException;
import com.xin.usermanagebackend.mapper.UserMapper;
import com.xin.usermanagebackend.model.dto.user.UserUpdateRequest;
import com.xin.usermanagebackend.model.entity.User;
import com.xin.usermanagebackend.model.vo.UserVo;
import com.xin.usermanagebackend.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* @author 鑫
* @description 针对表【user】的数据库操作Service实现
* @createDate 2023-04-25 10:53:35
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {
    @Resource
    private UserMapper userMapper;
    private static  final String SALT="xinxin";

    /**
     * 用户注册
     * @param userAccount  账号
     * @param userPassword  密码
     * @param checkPassword 确认密码
     * @return 用户主键id
     */
    @Override
    public long userRegister(String userAccount,String userPassword,String checkPassword) {
        //判断这三个是否为为null，和空字符
        if(StringUtils.isAnyBlank(userAccount,userPassword,checkPassword)){
            throw new BusinessException(ResultCode.PARAM_ERROR,"参数不能为空");
        }
        //账号长度
        if (userAccount.length()<4){
            throw new BusinessException(ResultCode.PARAM_ERROR,"账号长度不能小于4位");
        }
        //密码长度
        if(userPassword.length()<8) {
            throw new BusinessException(ResultCode.PARAM_ERROR,"密码长度不能小于8位");
        }
        //两次密码输入
        if(!userPassword.equals(checkPassword)) {
            throw new BusinessException(ResultCode.PARAM_ERROR,"两次密码密码不一致");
        }
        //密码特殊字符
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if (matcher.find()) {
            throw new BusinessException(ResultCode.PARAM_ERROR,"账号不能包含特殊字符");
        }
        //账号是否重复
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_account",userAccount);
        Long count = userMapper.selectCount(userQueryWrapper);
        if(count>0){
            throw new BusinessException(ResultCode.PARAM_ERROR,"该账号已经被注册");
        }
        //密码加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        // //保存用户注册的数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        boolean save = this.save(user);
        if(!save){
            throw new BusinessException(ResultCode.SYSTEM_ERROR,"注册失败");
        };
        return user.getId();
    }

    /**
     * 用户登录
     * @param userAccount 账号
     * @param userPassword  密码
     * @param httpServletRequest 请求
     * @return 用户信息
     */
    @Override
    public UserVo userLonin(String userAccount, String userPassword, HttpServletRequest httpServletRequest) {
        //判断这三个是否为为null，和空字符
        if(StringUtils.isAnyBlank(userAccount,userPassword)){
            throw new BusinessException(ResultCode.PARAM_ERROR,"参数不能为空");
        }
        //账号长度
        if (userAccount.length()<4){
            throw new BusinessException(ResultCode.PARAM_ERROR,"账号长度不能小于4位");
        }
        //密码长度
        if(userPassword.length()<8) {
            throw new BusinessException(ResultCode.PARAM_ERROR,"密码长度不能小于8位");
        }
        //密码特殊字符
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if (matcher.find()) {
            throw new BusinessException(ResultCode.PARAM_ERROR,"账号不能包含特殊字符");
        }

        //查询数据库账号密码是否相等
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        userQueryWrapper.eq("user_password",encryptPassword);
        userQueryWrapper.eq("user_account",userAccount);
        User user = userMapper.selectOne(userQueryWrapper);
        if(user==null){
            throw new BusinessException(ResultCode.PARAM_ERROR,"账号或密码错误");
        }
        //用户脱敏
        UserVo safetyUser = getSafetyUser(user);
        //session记录用户状体
        httpServletRequest.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,safetyUser);
        return  safetyUser;

    }

    @Override
    public Integer userLogout(HttpServletRequest httpServletRequest) {
        httpServletRequest.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);;
        return  1;
    }

    @Override
    public List<UserVo> searchUserByTags(List<String> tags) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        for (String tag : tags) {
            queryWrapper=queryWrapper.like("tags",tag);
        }
        List<User> users = userMapper.selectList(queryWrapper);
        return users.stream().map(this::getSafetyUser).collect(Collectors.toList());
    }

    @Override
    public Integer update(UserUpdateRequest userUpdateRequest) {
        User user = new User();
        BeanUtils.copyProperties(userUpdateRequest,user);
        int res = userMapper.updateById(user);
        return  res;
    }


    /**
     * 信息脱敏
     * @param originUser 原始信息
     * @return   返回处理原始对象一些信息的对象
     */
    public UserVo getSafetyUser(User originUser){
        if (originUser == null) {
            return null;
        }
        UserVo safetyUser = new UserVo();
        BeanUtils.copyProperties(originUser,safetyUser);
        return safetyUser;
    }
}




